// 箭头函数是 ES6 中新增的一种函数表达式，它的语法比传统的函数表达式更加简洁和易读。

// 将传统函数转换为箭头函数的一些样例

// 1. 没有参数；没有中间代码块逻辑，直接返回值的函数
let func1 = function () {
    return "Hello, World!";
};
// 转换为箭头函数
let func1_arrow = () => "Hello, World!";  // 参数作为等号后面第一个，返回值使用箭头指向
let func2_arrow2 = () => console.log("Hello, World!");


// 2. 没有参数；有中间代码块逻辑的函数
let func2 = function () {
    let a = 1;
    let b = 2;
    return a + b;
}
// 转换为箭头函数
let func2_arrow = () => {
    let a = 1;
    let b = 2;
    return a + b;
}  // 参数同样为空小括号，箭头指向中间代码块逻辑，使用大括号包裹，内容不变

// 3. 有参数，没有中间代码块逻辑，直接返回值的函数
let func3 = function (a, b) {
    return a + b;
}
// 转换为箭头函数
let func3_arrow = (a, b) => a + b;  // 直接在参数小括号中传入参数即可，返回值格式同上

// 箭头函数的调用
console.log("箭头函数的调用")
console.log(func1_arrow());  // 直接以函数名称调用即可
func2_arrow2();
console.log(func3_arrow(1, 2));


// 箭头函数的主要作用
console.log("箭头函数的主要作用")
// 箭头函数会将当前函数的作用域视为上一层的作用域，本身没有 this 指向
// 对比
// 普通函数
let obj = {
    name: "Tom",
    age: 23,
    sayHello() {
        console.log("Hello,", this.name, "!");
    }
}
// 调用 obj 的 sayHello，对应的 name 是调用者的 name，即 obj 的 name，Tom
obj.sayHello();

// 箭头函数
let name = "Emily"; // 定义在 obj2 之外层的 name
let obj2 = {
    name: "Tom",
    age: 23,
    // 普通函数
    sayHelloWithNormalFunction() {
        setTimeout(function () {  // 使用 setTimeout 更好演示箭头函数和普通函数的区别（setTimeout 会改变普通函数的 this 指向）
            console.log("Hello,", this.name, "!"); // this 指向全局作用域（浏览器中是 window，Node.js 中是 undefined）
        }, 1);
    },
    // 箭头函数
    sayHelloWithArrowFunction() {
        setTimeout(() => {
            console.log("Hello,", this.name, "!"); // this 继承自，定义 sayHelloWithArrowFunction 时的外层作用域，即 obj2
        }, 1);
    }
};
obj2.sayHelloWithNormalFunction(); // 输出: Hello, Emily! （this.name 指向全局变量 name，在 Node.js 中为 undefined）
obj2.sayHelloWithArrowFunction(); // 输出: Hello, Tom! （this.name 指向 obj2）